import {TempNode} from '../core/TempNode.js';
import {NodeLib} from '../core/NodeLib.js';

class NormalNode extends TempNode {

  constructor(scope) {

    super('v3');

    this.scope = scope || NormalNode.VIEW;

  }

  getShared() {

    // if shared is false, TempNode will not create temp variable (for optimization)

    return this.scope === NormalNode.WORLD;

  }

  build(builder, output, uuid, ns) {

    const contextNormal = builder.context[this.scope + 'Normal'];

    if (contextNormal) {

      return contextNormal.build(builder, output, uuid, ns);

    }

    return super.build(builder, output, uuid);

  }

  generate(builder, output) {

    let result;

    switch (this.scope) {

      case NormalNode.VIEW:

        if (builder.isShader('vertex')) result = 'transformedNormal';
        else result = 'geometryNormal';

        break;

      case NormalNode.LOCAL:

        if (builder.isShader('vertex')) {

          result = 'objectNormal';

        } else {

          builder.requires.normal = true;

          result = 'vObjectNormal';

        }

        break;

      case NormalNode.WORLD:

        if (builder.isShader('vertex')) {

          result = 'inverseTransformDirection( transformedNormal, viewMatrix ).xyz';

        } else {

          builder.requires.worldNormal = true;

          result = 'vWNormal';

        }

        break;

    }

    return builder.format(result, this.getType(builder), output);

  }

  copy(source) {

    super.copy(source);

    this.scope = source.scope;

    return this;

  }

  toJSON(meta) {

    let data = this.getJSONNode(meta);

    if (!data) {

      data = this.createJSONNode(meta);

      data.scope = this.scope;

    }

    return data;

  }

}

NormalNode.LOCAL = 'local';
NormalNode.WORLD = 'world';
NormalNode.VIEW = 'view';

NormalNode.prototype.nodeType = 'Normal';

NodeLib.addKeyword('viewNormal', function () {

  return new NormalNode(NormalNode.VIEW);

});

NodeLib.addKeyword('localNormal', function () {

  return new NormalNode(NormalNode.NORMAL);

});

NodeLib.addKeyword('worldNormal', function () {

  return new NormalNode(NormalNode.WORLD);

});

export {NormalNode};
